/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package GUIUtilities;

import java.util.Collections;
import java.util.List;
import java.util.Vector;
import multiarray.MultiArray;
import multiarray.RecursiveAccess;

/**
 *
 * @author Heather
 */
public abstract class ListUtilities
{

  public static String getStringVectorString(Vector<String> input)
  {
    String ret = "[";

    for (int i = 0; i < input.size() - 1; i++)
    {
      ret += input.get(i) + ", ";
    }
    ret += input.get(input.size() - 1) + "]";

    return ret;
  }

  public static Vector<int[]> sortByPop(List<int[]> input, IntVectorComparator comparator)
  {
    comparator.setComparitor(IntVectorComparator.ComparatorSettings.population);
    Vector<Vector<Integer>> vInput = convertToVector(input);
    Collections.sort(vInput, comparator);
    return convertToArray(vInput);
  }

  public static Vector<int[]> sortByPower(List<int[]> input, IntVectorComparator comparator)
  {
    comparator.setComparitor(IntVectorComparator.ComparatorSettings.power);
    Vector<Vector<Integer>> vInput = convertToVector(input);
    Collections.sort(vInput, comparator);
    return convertToArray(vInput);
  }

  public static Vector<Vector<Integer>> convertToVector(List<int[]> input)
  {
    Vector<Vector<Integer>> ret = new Vector<Vector<Integer>>();

    for (int[] i : input)
    {
      Vector<Integer> v = new Vector<Integer>();

      for (int j : i)
      {
        v.add(j);
      }

      ret.add(v);
    }

    return ret;
  }

  public static Vector<int[]> convertToArray(Vector<Vector<Integer>> input)
  {
    Vector<int[]> ret = new Vector<int[]>();

    for (Vector<Integer> v : input)
    {
      int[] i = new int[v.size()];

      for (int j = 0; j < v.size(); j++)
      {
        i[j] = v.get(j);
      }

      ret.add(i);
    }

    return ret;
  }

  public static boolean compareArrays(int[] a, int[] b)
  {
    if (a.length != b.length)
    {
      return false;
    }
    else
    {
      for (int i = 0; i < a.length; i++)
      {
        if (a[i] != b[i])
        {
          return false;
        }
      }
      return true;
    }
  }

  public static String getIntArrayString(int[] input)
  {
    String ret = "[";

    for (int i = 0; i < input.length - 1; i++)
    {
      ret += input[i] + ", ";
    }
    ret += input[input.length - 1] + "]";

    return ret;
  }

  public static String getStringListString(List<String> input)
  {
    String ret = "[";

    for (int i = 0; i < input.size() - 1; i++)
    {
      ret += input.get(i) + ", ";
    }
    ret += input.get(input.size() - 1) + "]";

    return ret;
  }

  public static MultiArray<MultiArray<Double>> convertFloatsToDoubles(MultiArray<MultiArray<Float>> input)
  {
    MultiArray<MultiArray<Double>> ret = new MultiArray<MultiArray<Double>>(input.getDimensions());
    int[] sizes = input.getDimensions();
    int[] indices = new int[sizes.length];
    for (int i = 0; i < indices.length; i++)
    {
      indices[i] = -1;
    }

    List<int[]> allCombos = RecursiveAccess.generateAllPermutations(indices, sizes);

    for (int[] i : allCombos)
    {
      MultiArray<Double> newEntry = new MultiArray<Double>(input.getDimensions());
      MultiArray<Float> oldEntry = input.getElementAtIndex(i);

      for (int[] j : allCombos)
      {
        newEntry.setElementAtIndex(j, (double) oldEntry.getElementAtIndex(j));
      }

      ret.setElementAtIndex(i, newEntry);
    }

    return ret;
  }

  public static MultiArray<MultiArray<Float>> convertDoublesToFloats(MultiArray<MultiArray<Double>> input)
  {
    MultiArray<MultiArray<Float>> ret = new MultiArray<MultiArray<Float>>(input.getDimensions());
    int[] sizes = input.getDimensions();
    int[] indices = new int[sizes.length];
    for (int i = 0; i < indices.length; i++)
    {
      indices[i] = -1;
    }

    List<int[]> allCombos = RecursiveAccess.generateAllPermutations(indices, sizes);

    for (int[] i : allCombos)
    {
      MultiArray<Float> newEntry = new MultiArray<Float>(input.getDimensions());
      MultiArray<Double> oldEntry = input.getElementAtIndex(i);

      for (int[] j : allCombos)
      {
        newEntry.setElementAtIndex(j, (float) oldEntry.getElementAtIndex(j).doubleValue());
      }

      ret.setElementAtIndex(i, newEntry);
    }

    return ret;
  }

  // returns true if l1 has the same elements as l2
  public static boolean doCoalitionsHaveSameElements(List<int[]> l1, List<int[]> l2)
  {
    // first check size
    if (l1.size() != l2.size())
    {
      System.out.println("coalition sizes mismatch");
      return false;
    }

    //keeps track of which elements we've already examined
    Vector<Integer> seen = new Vector<Integer>();

    for (int i = 0; i < l1.size(); i++)
    {
      boolean found = false;
      for (int j = 0; j < l2.size(); j++)
      {
        if (!seen.contains(j))
        {
          if (compareArrays(l1.get(i), l2.get(j)))
          {
            found = true;
            seen.add(j);
            break;
          }
        }
      }

      if (!found)
      {
        System.out.println("could not find group in coalition");
        System.out.println("i is: " + i + ", " + ListUtilities.getIntArrayString(l1.get(i)));
        return false;
      }
    }

    return true;
  }

  public static boolean doPartitionsHaveSameElements(List<List<int[]>> l1, List<List<int[]>> l2)
  {
    if (l1.size() != l2.size())
    {
      System.out.println("partition sizes mismatch");
      return false;
    }

    //keeps track of which elements we've already examined
    Vector<Integer> seen = new Vector<Integer>();

    for (int i = 0; i < l1.size(); i++)
    {
      boolean found = false;
      for (int j = 0; j < l2.size(); j++)
      {
        if (!seen.contains(j))
        {
          if (doCoalitionsHaveSameElements(l1.get(i), l2.get(j)))
          {
            found = true;
            seen.add(j);
            break;
          }
        }
      }

      if (!found)
      {
        System.out.println("could not find coalition in partition");
        return false;
      }
    }

    return true;
  }
}
